package models

import (
	"blog_api/db"
	"strconv"
)

type Article struct {
	Id          uint64 `gorm:"column(id)" json:"id"`
	Title       string `gorm:"column(title)" json:"title"`
	Content     string `gorm:"column(content)" json:"content"`
	Author      string `gorm:"column(author)" json:"author"`
	LabelId     int    `gorm:"column(label_id)" json:"label_id"`
	CatId       int    `gorm:"column(cat_id)" json:"cat_id"`
	ImgUrl      string `gorm:"column(img_url)" json:"img_url"`
	IsHot       int    `gorm:"column(is_hot)" json:"is_hot"`
	IsShow      int    `gorm:"column(is_show)" json:"is_show"`
	IsDel       int    `gorm:"column(is_del)" json:"is_del"`
	AddTime     uint64 `gorm:"column(add_time)" json:"add_time"`
	UpdateTime  uint64 `gorm:"column(update_time)" json:"update_time"`
	ViewNumbers int    `gorm:"column(view_numbers)" json:"view_numbers"`
}

func (*Article) TableName() string {
	return "blog_article"
}

const (
	ARTILCE_TOP       = "artilce_top"
	ES_ARTILCE_INDEX  = "articles_index"
	ES_LABEL_INDEX    = "label_index"
	ES_CATEGORY_INDEX = "category_index"
	ES_SET_INDEX      = "set_index"
)

type HotArt struct {
	Id          uint64 `gorm:"column(id)" json:"id"`
	Title       string `gorm:"column(title)" json:"title"`
	CatId       int    `gorm:"column(cat_id)" json:"cat_id"`
	ViewNumbers int    `gorm:"column(view_numbers)" json:"view_numbers"`
}

/**
 * HotArticleList
 * @Description: 首推荐文章列表
 * @Author: Jazk-Z
 * @param limit
 * @return []HotArt
 */
func HotArticleList(limit string) []HotArt {
	li, _ := strconv.Atoi(limit)
	hot_art_exixt, _ := db.RedisExists(ARTILCE_TOP)
	sel := db.Mysql.Model(&Article{})
	var hotart []HotArt
	if hot_art_exixt == 0 {
		sel.Where("is_show = ? and is_del = ?", 1, 0)
		sel.Order("view_numbers desc").Limit(li).Scan(&hotart)
		var member struct {
			Score  float64
			Member interface{}
		}
		for _, v := range hotart {
			member.Score = float64(v.ViewNumbers)
			member.Member = v.Id
			db.RedisZAdd(ARTILCE_TOP, member)
		}
	} else {
		hot_art_ids, _ := db.RedisZRevRange(ARTILCE_TOP, 0, -1)
		sel.Where("is_show = ? and is_del = ?", 1, 0)
		sel.Where("id in (?)", hot_art_ids)
		sel.Order("view_numbers desc").Limit(li).Scan(&hotart)
	}
	return hotart
}

func ArtCount() int64 {
	var ac int64
	db.Mysql.Model(&Article{}).Where("is_del", 0).Count(&ac)
	return ac
}

/**
 * ArticleListByCat
 * @Description: 首页文章列表
 * @Author: Jazk-Z
 * @param limit
 * @param offset
 * @param cat_id
 * @param keyword
 * @return []map[string]interface{}
 * @return int64
 */
func ArticleListByCat(limit, offset, cat_id, lid int, keyword string, action_type int) ([]map[string]interface{}, int64) {
	var list []map[string]interface{}
	sel := db.Mysql.Table("blog_article as a")

	if keyword != "" {
		ids, err := db.SearchKeyword(keyword, ES_ARTILCE_INDEX)
		if err != nil {
			return list, 0
		}
		sel.Where("a.id in (?)", ids)
	}

	if action_type == 0 {
		sel.Where("a.is_del = ? and a.is_show = ?", 0, 1)

		if cat_id > 0 {
			var cat_info Category
			db.Mysql.Model(&Category{}).Where("id", cat_id).Scan(&cat_info)
			if cat_info.ParentId == 0 {
				var cat_ids []int
				db.Mysql.Model(&Category{}).Where("parent_id", cat_id).Select("id").Scan(&cat_ids)
				sel.Where("a.cat_id in (?)", cat_ids)
			} else {
				sel.Where("a.cat_id", cat_id)
			}
		} else if lid > 0 {
			sel.Where("a.label_id", lid)
		}
	}
	var c int64
	sel.Count(&c)
	sel.Joins("left join blog_category as c on a.cat_id = c.id")
	sel.Select("a.*, c.cat_name").Limit(limit)
	sel.Order("a.add_time desc").Offset(offset).Scan(&list)
	return list, c
}

/**
 * ArticleDetailById
 * @Description: 通过id获取文章详情
 * @Author: Jazk-Z
 * @param id
 * @return map[string]interface{}
 * @return int64
 */
func ArticleDetailById(id string) (map[string]interface{}, error) {
	var c int64
	var ad map[string]interface{}

	err := db.Mysql.Model(&Article{}).Where("id", id).Count(&c).Error
	if c == 0 {
		return ad, err
	}
	sel := db.Mysql.Table("blog_article as a").
		Joins("left join blog_category as c on a.cat_id=c.id").
		Joins("left join blog_label as l on a.label_id=l.id").
		Where("a.is_del = ? and a.is_show =? and a.id = ?", 0, 1, id).
		Select("a.*, c.cat_name, l.label_name").
		Scan(&ad).Error
	return ad, sel
}
